// =================================================================
// File: parse.cpp
// Desc: Contains function for parsing user commands and arguments.
// =================================================================

// =================================================================
// INCLUDES
// =================================================================

#include <string>
#include <vector>
#include <iostream>
#include "FSManager.h"
#include "commands.h"
#include "Tokenize.h"
#include "config.h"

// =================================================================
// FUNCTIONS
// =================================================================

// =================================================================
// Name: changeNewLine
// Desc: Converts the '\n' to the actually new line character.
// Args: string &data - a reference to the data for write.
// =================================================================

void changeNewLine(string &data){
  string newData = "";
  string delimit = "\\n";

  for(unsigned int i = 0; i < data.length(); i++){
    if(data[i] == '\\' && data[i+1] == 'n'){
      data[i] = '\n';
      data.erase((i+1),1);
    }
  }
}

// =================================================================
// Name: changeNewLine
// Desc: Separates the line of commands into its parts, such as the
//	 the command name, and the arguments for that command.
// Args: string line - the line that the user input with commands in it.
//       FSManager* fsm - pointer to FSManager object in use
// =================================================================

void parse(string line, FSManager *fsm){

  size_t  space = line.find_first_of(" ");
  string command = line.substr(0,(int)space);
  string arg1,arg2;

  line.erase(0,command.length()+1);
  if(command != "ls" && command != "mkfs" && command != "tree" && command !="exit"){
    if(line.length() == 0){
      cout << "COMMAND IS INVALID" << endl;
      return;
    }
  }

  if(line.length() != 0){
    space = line.find_first_of(" ");
    arg1 = line.substr(0,(int)space);
    line.erase(0,arg1.length()+1);

    if(line.length() != 0){
      arg2 = line.substr(0,line.length());
    }
  }


  if(command == "mkfs"){
/*    delete fsm;
    remove(FS_NAME);
    fsm = new FSManager(FS_NAME);*/
    fsm->Reset();
    mkfs(fsm);
    cout << "File system initialized" << endl;
  }

  else if(command == "open"){
    int fd  = open(arg1,arg2,fsm);
    if(fd != -1){
      cout << "SUCCESS, fd = " << fd << endl;
    }
    else{
      cerr << "FAILED TO OPEN " << arg1 << endl;
    }
  }

  else if(command == "close"){
    int fd = atoi(arg1.c_str());

    close(fd,fsm);
    cout << "fd = " << fd << " is now closed." << endl;
  }
  else if(command == "write"){
    int fd = atoi(arg1.c_str());

    string data = arg2;

    size_t first_quote = data.find_first_of("\"");
    size_t  last_quote = data.find_last_of("\"");
    data = data.substr(first_quote+1,last_quote-1);
    changeNewLine(data);

    int success = write(fd,data,fsm);
    if (success >= 0)
      cout << "Wrote " << success << " bytes to fd = " << fd << endl;
    else
      cout << "Unsuccessful in write to fd = " << fd << endl;
  }
  else if(command == "read"){
    int fd = atoi(arg1.c_str());
    int bytesToRead = atoi(arg2.c_str());

    string ret = read(fd,bytesToRead,fsm);
    ret += '\0';
    cout << ret << endl;
  }
  else if(command == "seek"){
    int fd = atoi(arg1.c_str());
    int offset = atoi(arg2.c_str());

    int success = seek(fd,offset,fsm);
    if (success == 0)
      cout << "Seek on " << fd << " by " << offset << " bytes successful." << endl;
    else
      cerr << "Seek on " << fd << " by " << offset << " bytes unsuccessful." << endl;
      
  }

  else if(command == "mkdir"){
    mkdir(arg1,fsm);
  }

  else if(command == "rmdir"){
    rmdir(arg1,fsm);
  }

  else if(command == "link"){
    link(arg1,arg2,fsm);
  }
  else if(command == "unlink"){
    unlink(arg1,fsm);
  }

  else if(command == "cd"){
    cd(arg1,fsm);
  }

  else if(command == "cat"){
    cat(arg1,fsm);
  }

  else if(command == "ls"){
    ls(fsm);
  }
  else if(command == "exit"){
    delete fsm;
  }
  else if(command == "tree"){
    tree(fsm);
  }
  else if(command == "stat") {
    stat(arg1, fsm);
  }
  else if(command == "cp"){
    int ret = cp(arg1,arg2,fsm);
    if(ret == -1){
      cout << "FILE ALREADY EXISTS" << endl;
    }
  }
  else if(command == "import"){
    import(arg1,arg2,fsm);
  }
  else if(command == "export"){
    Export(arg1,arg2,fsm);
  }

}
